#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include "../include/menu.h"

struct option longOpt[] ={
    {"help", no_argument, NULL, 'h'},
    {"in", required_argument, NULL,'i'},
    {"out", required_argument, NULL,'o'},
    {"encription", no_argument, NULL,'e'},
    {"decription", no_argument, NULL,'d'},
    {"pass", required_argument, NULL,'p'},
    {"key", required_argument, NULL,'k'},
    {"iv", required_argument, NULL,'v'},
    {"algorith", required_argument, NULL,'a'},
    {"method", required_argument, NULL,'m'},
};

static void init(appInit *params);

void
freeParameters(appInit *p)
{
    if (p == NULL)
        return;

    if (p->algorithm != NULL)
        free(p->algorithm);

    if (p->method != NULL)
        free(p->method);

    if (p->inName != NULL)
        free(p->inName);

    if (p->outName != NULL)
        free(p->outName);

    if (p->password != NULL)
        free(p->password);

    if (p->key != NULL)
        free(p->key);

    if (p->iv != NULL)
        free(p->iv);

    return;
}

int
validateParameters(appInit *params)
{
    char *ptr;

    if (params == NULL)
        return 0;

    if ( params->error == 1 )
        return 0;

    if ( params->inName == NULL || params->outName == NULL )
        return 0;

    if ( params->password == NULL && (params->key == NULL || params-> iv == NULL) )
        return 0;

    if ( params->password != NULL )
        if ( params->key != NULL || params-> iv != NULL )
            return 0;

    if ( params->opQuantity != 1 )
        return 0;

    if ( params->op != 'e' && params->op != 'd' )
        return 0;

    if ( params->algorithm == NULL )
        return 0;

    if ( strcmp(params->algorithm, "aes") != 0 &&
         strcmp(params->algorithm, "des") != 0 )
        return 0;

    if ( params->method == NULL )
        return 0;

    if ( strcmp(params->method, "ecb") != 0 && strcmp(params->method, "cfb") &&
        strcmp(params->method, "ofb") && strcmp(params->method, "cbc") )
        return 0;

    return 1;
}

static void
init(appInit *params) {
    params->opQuantity = 0;
    params->error = 0;
    params->op = ' ';
    params->algorithm = NULL;
    params->method = NULL;
    params->inName = NULL;
    params->outName = NULL;
    params->password = NULL;
    params->key = NULL;
    params->iv = NULL;

    return;
}

int
getParameters(int argc, char *argv[], appInit *params)
{
    int nextOpt;

    if(params == NULL)
        return -1;

    /*Params gets initialized*/
    init(params);

    while( (nextOpt = getopt_long(argc, argv,"edhi:o:p:k:v:a:m:", longOpt, NULL)) != -1 )
    {
        switch( nextOpt )
        {
                    case 'h':
                        params->op = 'h';
                        params->opQuantity++;
                        return -1;
                        break;

                    case 'i':
                        params->inName = strdup(optarg);
                        break;

                    case 'o':
                        params->outName = strdup(optarg);
                        break;

                    case 'e':
                        params->op = 'e';
                        params->opQuantity++;
                        break;

                    case 'd':
                        params->op = 'd';
                        params->opQuantity++;
                        break;

                    case 'p':
                        params->password = strdup(optarg);
                        break;

                    case 'k':
                        params->key = strdup(optarg);
                        break;

                    case 'v':
                        params->iv = strdup(optarg);
                        break;

                    case 'a':
                        params->algorithm = strdup(optarg);
                        break;

                    case 'm':
                        params->method = strdup(optarg);
                        break;

                    case '?':
                    case -1:
                    default:
                        params->error = 1;
                        break;
                }
        }

    return 1;
}

void
usage(char *prgName)
{

    printf("Usage: %s options\n\n", prgName);
    printf(" -h,    --help                                        \n");
    printf("                  Help is printed.                  \n\n");
    printf(" -i,    --in                                          \n");
    printf("                  Path to the in image.             \n\n");
    printf(" -o,    --out                                         \n");
    printf("                  Path to the output image.         \n\n");
    printf(" -e,    --encription                                  \n");
    printf("                  Encripts the file.                \n\n");
    printf(" -d,    --decription                                  \n");
    printf("                  Decripts the file.                \n\n");
    printf(" -p     --pass                                        \n");
    printf("                  Password to use.                  \n\n");
    printf(" -k     --key                                         \n");
    printf("                  Key to use.                       \n\n");
    printf(" -v     --iv                                          \n");
    printf("                  Initilize Vector to use.          \n\n");
    printf(" -a     --algorithm                                   \n");
    printf("                  Algorithm to use.                 \n\n");
    printf(" -m     --method                                      \n");
    printf("                  Method to use.                    \n\n");
    printf(" Example:                                             \n");
    printf(" To encript in.bmp with DES CBC and password secret:  \n");
    printf(" encrypter -e -i in.bmp -o out.bmp -a des -m cbc -p secret\n\n");
    printf(" To encript in.bmp with AES CBC and password secret:  \n");
    printf(" encrypter -e -i in.bmp -o out.bmp -a aes -m cbc -p secret\n\n");


    return;
}
